package com.middlegroup.pay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.middlegroup.common.enums.ChannelCode;
import com.middlegroup.common.enums.ServiceType;
import com.middlegroup.common.exception.ErrorMsg;
import com.middlegroup.common.model.*;
import com.middlegroup.common.utils.AesUtils;
import com.middlegroup.common.utils.RSAUtils;
import com.middlegroup.pay.dto.RouterRequest;
import com.middlegroup.pay.dto.RouterResponse;
import com.middlegroup.pay.entity.InBills;
import com.middlegroup.pay.entity.Merchant;
import com.middlegroup.pay.entity.OutNotifyMerchantLog;
import com.middlegroup.pay.entity.RefundBills;
import com.middlegroup.pay.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.security.PrivateKey;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

/**
 *
 * @author pc
 * @date 2019/1/25
 */
@Service
@Slf4j
public class NotifyMerchantServiceImpl implements NotifyMerchantService {
    @Resource
    private SystemCfgService systemCfgService;
    @Resource
    private MerchantService merchantService;
    @Resource
    private OutNotifyMerchantLogService outNotifyMerchantLogService;
    public void postMerchant(NotifyRequest request, String url,String merchantCode){

        //商户回调日志记录
        OutNotifyMerchantLog outNotifyMerchantLog = new OutNotifyMerchantLog();
        outNotifyMerchantLog.setStatus(0);
        outNotifyMerchantLog.setMerchantBillNo(request.getMerchantBillNo());
        outNotifyMerchantLog.setBillNo(StringUtils.isEmpty(request.getBillNo())?request.getMerchantRefundNo():request.getBillNo());
        outNotifyMerchantLog.setMerchantCode(merchantCode);
        outNotifyMerchantLog.setBeginTime(System.currentTimeMillis());
        String privateKeyStr = systemCfgService.getConfigString("pay_platform","rsa_pri_key");
        String aesKey = RandomStringUtils.randomAlphanumeric(16);
        String reqData = null;
        Merchant merchant = merchantService.getMerchantByCode(merchantCode);
        String platformPublicKey= merchant.getRsaPubKey();
        log.debug("+++++++ privateKeyStr:{}", privateKeyStr);
        log.debug("+++++++ platformPublicKey:{}", platformPublicKey);
        //使用明文aesKey加密业务数据
        try {
            reqData = AesUtils.encrypt(JSONObject.toJSONString(request), aesKey);
        } catch (Exception e) {
            return;
        }
        //使用商户公钥加密aesKey
        try {
            aesKey = new String(com.middlegroup.common.utils.Base64Utils.encode(RSAUtils.encryptByPublicKey(aesKey.getBytes("UTF-8"), platformPublicKey)));
        } catch (Exception e) {
            return;
        }
        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        postParameters.add("aesKey", aesKey);
        postParameters.add("merchantCode", merchantCode);
        postParameters.add("reqData", reqData);
        Map<String, String> params = new TreeMap<String, String>();
        params.put("aesKey", aesKey);
        params.put("reqData", reqData);
        String jsoStr = JSONObject.toJSONString(params);
        //中台私钥签名
        PrivateKey privateKey = RSAUtils.readPrivateKey(privateKeyStr);
        String sign = null;
        try {
            sign = RSAUtils.sign("SHA1WithRSA", jsoStr.getBytes("UTF-8"), privateKey);
        } catch (Exception e) {
            return;
        }
        postParameters.add("sign", sign);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity responseDto = null;
        outNotifyMerchantLog.setRequestText(JSONObject.toJSONString(postParameters));
        try {
            responseDto = restTemplate.postForObject(url, postParameters, ResponseEntity.class);
            outNotifyMerchantLog.setResponseText(JSONObject.toJSONString(responseDto));
        } catch (Exception e) {
            log.error("回调通知商户异常", e);
            //异常
            outNotifyMerchantLog.setStatus(2);
        }
        if("1".equals(responseDto.getStatus())){
            outNotifyMerchantLog.setStatus(1);
        }else{
            outNotifyMerchantLog.setStatus(2);
        }
        outNotifyMerchantLog.setEndTime(System.currentTimeMillis());
        outNotifyMerchantLogService.insert(outNotifyMerchantLog);
    }
}